package com.example;
// 避免在构造方法中调用重写的方法
/**
 * 父类B：在构造方法中调用可重写方法（危险做法）
 * 该类展示了在构造方法中调用可重写方法可能带来的问题
 */
class B {
    /**
     * 父类构造方法
     * 危险：在构造方法中调用可重写的实例方法
     * 当子类继承此类时，可能在此处调用子类重写的方法
     */
    public B() {
        // 问题点：在对象构造过程中调用可重写方法
        // 此时子类对象尚未完全初始化，成员变量可能处于未初始化状态
        func();  // 由于多态机制，实际可能调用子类重写的版本
    }

    /**
     * 可重写的方法
     * 此方法可能被子类重写，在子类中访问子类特有的成员变量
     */
    public void func() {
        System.out.println("B.func() - 父类方法安全执行");
    }
}

/**
 * 子类D：重写父类的func方法
 * 该类继承自B，并重写了func方法，同时拥有自己的成员变量
 */
class D extends B {
    /**
     * 子类成员变量，声明时初始化为1
     * 重要：这个初始化操作在父类构造方法执行之后才进行
     */
    private int num = 1;

    /**
     * 子类构造方法
     * 隐式调用父类构造方法，然后执行子类成员初始化和构造方法体
     */
    public D() {
        // 隐式调用super() - 即父类B的构造方法
        // 然后初始化成员变量 num = 1
        // 最后执行子类构造方法体（本例中为空）
    }

    /**
     * 重写父类的func方法
     * 风险：在父类构造方法中被调用时，num尚未初始化
     * 此时访问num将得到默认值0，而不是期望的1
     */
    @Override
    public void func() {
        // 危险：在父类构造方法中调用时，num还未被初始化为1
        System.out.println("D.func() - num = " + num);
    }

    public static void main(String[] args) {
        System.out.println("创建子类D对象...");
        D d = new D();  // 创建子类对象，触发问题

        System.out.println("\n对象创建完成后调用func方法：");
        d.func();  // 正常调用，此时num已正确初始化
    }
}




/* 执行结果：
创建子类D对象...
D.func() - num = 0   （问题出现：num输出0，而不是期望的1）

对象创建完成后调用func方法：
D.func() - num = 1   （正常情况：num正确输出1）
*/